package com.uoko.common.collection;

import java.util.Comparator;
import java.util.Date;

/**
 * <p>
 * 这个东东其实就是用来做数字,字符串,日期的默认比较,其实如果你要用guava等,完全没必要用这个,但是如果你不想用guava,
 * 这个应该是对你来说一个不错的选择。
 * </p>
 *
 * @author chenyingchun
 * Email qiaohai@uoko.com
 * created by 2018/6/6 0006
 */
public abstract class Comparators {

	public static class ObjectComparator implements Comparator<Object> {

		@Override
		public int compare(Object o1, Object o2) {
			return Comparators.compareObject(o1, o2);
		}

	}

	/**
	 * 默认的数字比较。null在前。
	 * 
	 * @author chenyingchun
	 *
	 */
	public static class NumberComparator implements Comparator<Number> {

		@Override
		public int compare(Number o1, Number o2) {
			return Comparators.compare(o1, o2);
		}

	}

	/**
	 * 默认的字符串比较。null在前。
	 * 
	 * @author chenyingchun
	 *
	 */
	public static class StringComparator implements Comparator<String> {

		@Override
		public int compare(String o1, String o2) {
			return Comparators.compare(o1, o2);
		}
	}

	/**
	 * 默认的日期比较,null在前
	 * 
	 * @author chenyingchun
	 *
	 */
	public static class DateComparator implements Comparator<Date> {

		@Override
		public int compare(Date o1, Date o2) {
			return Comparators.compare(o1, o2);
		}

	}

	public static class ObjectNullLastComparator implements Comparator<Object> {

		@Override
		public int compare(Object o1, Object o2) {
			return Comparators.compareObjectNullsLast(o1, o2);
		}

	}

	/**
	 * 默认的数字比较,null在后
	 * 
	 * @author chenyingchun
	 *
	 */
	public static class NumberNullLastComparator implements Comparator<Number> {

		@Override
		public int compare(Number o1, Number o2) {
			return Comparators.compareNullsLast(o1, o2);
		}

	}

	/**
	 * 默认的字符串比较,null在后
	 * 
	 * @author chenyingchun
	 *
	 */
	public static class StringNullLastComparator implements Comparator<String> {

		@Override
		public int compare(String o1, String o2) {
			return Comparators.compareNullsLast(o1, o2);
		}

	}

	/**
	 * 默认的日期比较,null在后
	 * 
	 * @author chenyingchun
	 *
	 */
	public static class DateNullLastComparator implements Comparator<Date> {

		@Override
		public int compare(Date o1, Date o2) {
			return Comparators.compareNullsLast(o1, o2);
		}

	}

	/** String排序器,按照Ascii排序,默认Null排在最前 **/
	public static final Comparator<Object> OBJECT_COMPARATOR = new ObjectComparator();
	/** String排序器,按照Ascii排序,默认Null排在最前 **/
	public static final Comparator<String> STRING_COMPARATOR = new StringComparator();
	/** Date排序器,按照时间先后排序,默认Null排在最前 **/
	public static final Comparator<Date> DATE_COMPARATOR = new DateComparator();
	/** 数字排序器(包括所有Integer,float,Double等等),默认Null排在最前 **/
	public static final Comparator<Number> NUMBER_COMPARATOR = new NumberComparator();
	/** String排序器,按照Ascii排序,Null排在最后 **/
	public static final Comparator<String> STRING_NULLSLAST = new StringNullLastComparator();
	/** Date排序器,按照时间先后排序,Null排在最后 **/
	public static final Comparator<Date> DATE_NULLSLAST = new DateNullLastComparator();
	/** 数字排序器(包括所有Integer,float,Double等等),Null排在最后 **/
	public static final Comparator<Number> NUMBER_NULLSLAST = new NumberNullLastComparator();

	/**
	 * 通用比较。null在前。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static <T> int compareObject(T o1, T o2) {
		if (o1 == null || o2 == null)
			return compareNullsFirst(o1, o2);
		if (o1 instanceof Comparable)
			return ((Comparable) o1).compareTo(o2);
		if (o1 instanceof Number)
			return compare((Number) o1, (Number) o2);
		return 0;
	}

	/**
	 * 数字通用比较null在前。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int compare(Number o1, Number o2) {
		if (o1 == null || o2 == null)
			return compareNullsFirst(o1, o2);
		double n = o1.doubleValue() - o2.doubleValue();
		if (n > 0)
			return 1;
		else if (n < 0)
			return -1;
		else
			return 0;
	}

	/**
	 * 日期时间通用比较null在前。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int compare(Date o1, Date o2) {
		if (o1 == null || o2 == null)
			return compareNullsFirst(o1, o2);
		return o1.compareTo(o2);
	}

	/**
	 * 字符串通用比较null在前。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int compare(String o1, String o2) {
		if (o1 == null || o2 == null)
			return compareNullsFirst(o1, o2);
		return o1.compareTo(o2);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static <T> int compareObjectNullsLast(T o1, T o2) {
		if (o1 == null || o2 == null)
			return compareNullsLast(o1, o2);
		if (o1 instanceof Comparable)
			return ((Comparable) o1).compareTo(o2);
		if (o1 instanceof Number)
			return compare((Number) o1, (Number) o2);
		return 0;
	}

	/**
	 * 数字通用比较null在后。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int compareNullsLast(Number o1, Number o2) {
		if (o1 == null || o2 == null)
			return compareNullsLast(o1, o2);
		double n = o1.doubleValue() - o2.doubleValue();
		if (n > 0)
			return 1;
		else if (n < 0)
			return -1;
		else
			return 0;
	}

	/**
	 * 日期时间通用比较null在后。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int compareNullsLast(Date o1, Date o2) {
		if (o1 == null || o2 == null)
			return compareNullsLast(o1, o2);
		return o1.compareTo(o2);
	}

	/**
	 * 字符串通用比较null在后。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int compareNullsLast(String o1, String o2) {
		if (o1 == null || o2 == null)
			return compareNullsLast(o1, o2);
		return o1.compareTo(o2);
	}

	/**
	 * 反转比较null在后。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int reverse(Number o1, Number o2) {
		if (o1 == null || o2 == null)
			return compareNullsLast(o1, o2);
		double n = o1.doubleValue() - o2.doubleValue();
		if (n > 0)
			return -1;
		else if (n < 0)
			return 1;
		else
			return 0;
	}

	/**
	 * 反转比较null在后。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int reverse(Date o1, Date o2) {
		if (o1 == null || o2 == null)
			return compareNullsLast(o1, o2);
		return o2.compareTo(o1);
	}

	/**
	 * 反转比较null在后。
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int reverse(String o1, String o2) {
		if (o1 == null || o2 == null)
			return compareNullsLast(o1, o2);
		return o2.compareTo(o1);
	}

	/**
	 * 反转比较null在前
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int reverseNullFirst(Number o1, Number o2) {
		if (o1 == null || o2 == null)
			return compareNullsFirst(o1, o2);
		double n = o1.doubleValue() - o2.doubleValue();
		if (n > 0)
			return -1;
		else if (n < 0)
			return 1;
		else
			return 0;
	}

	/**
	 * 反转比较,null在前
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int reverseNullFirst(Date o1, Date o2) {
		if (o1 == null || o2 == null)
			return compareNullsFirst(o1, o2);
		return o2.compareTo(o1);
	}

	/**
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int reverseNullFirst(String o1, String o2) {
		if (o1 == null || o2 == null)
			return compareNullsFirst(o1, o2);
		return o2.compareTo(o1);
	}

	/**
	 * 如果都为空或者都不为空那么久返回0,否则返回比较的结果是：非null大于null,排序的时候null在前;
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int compareNullsFirst(Object o1, Object o2) {
		if (o1 == null && o2 != null)
			return -1;
		else if (o1 != null && o2 == null)
			return 1;
		else
			return 0;
	}

	/**
	 * 如果都为空或者都不为空那么久返回0,否则返回比较的结果是：非null小于null,排序时null在后;
	 * 
	 * @param o1
	 * @param o2
	 * @return
	 */
	public static int compareNullsLast(Object o1, Object o2) {
		if (o1 == null && o2 != null)
			return 1;
		else if (o1 != null && o2 == null)
			return -1;
		else
			return 0;
	}

}
